﻿using System;
using System.IO;
using System.Windows.Controls;
using System.ComponentModel;
using System.Text;
using System.Windows.Markup;
using System.Globalization;
using System.Xml;

#if (SILVERLIGHT)

namespace nRoute.Components.TypeConverters
{
    /// <summary>
    /// From Microsoft.Expression.Interactions, Version=2.0.5.0
    /// </summary>
    public class ConvertFromStringConverter
		 : TypeConverter
    {
        private Type type;

        public ConvertFromStringConverter(Type type)
        {
            this.type = type;
        }

        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            if ((sourceType != typeof(string)) && (sourceType != typeof(uint)))
            {
                return base.CanConvertFrom(context, sourceType);
            }
            return true;
        }

        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            return ((typeof(IConvertible).IsAssignableFrom(this.type) && typeof(IConvertible).IsAssignableFrom(destinationType)) || base.CanConvertTo(context, destinationType));
        }

        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            string a = value as string;
            if (a != null)
            {
                Type nullableType = this.type;
                Type underlyingType = Nullable.GetUnderlyingType(nullableType);
                if (underlyingType != null)
                {
                    if (string.Equals(a, "null", StringComparison.OrdinalIgnoreCase))
                    {
                        return null;
                    }
                    nullableType = underlyingType;
                }
                else if (nullableType.IsGenericType)
                {
                    return base.ConvertFrom(context, culture, value);
                }
                object obj2 = new object();
                object content = obj2;
                if (nullableType == typeof(bool))
                {
                    content = bool.Parse(a);
                }
                else if (nullableType.IsEnum)
                {
                    content = Enum.Parse(this.type, a, false);
                }
                else
                {
                    StringBuilder builder = new StringBuilder();
                    builder.Append("<ContentControl xmlns='http://schemas.microsoft.com/client/2007' xmlns:c='" + ("clr-namespace:" + nullableType.Namespace + ";assembly=" + nullableType.Assembly.FullName.Split(new char[] { ',' })[0]) + "'>\n");
                    builder.Append("<c:" + nullableType.Name + ">\n");
                    builder.Append(a);
                    builder.Append("</c:" + nullableType.Name + ">\n");
                    builder.Append("</ContentControl>");

                    ContentControl control = XamlReader.Load(builder.ToString()) as ContentControl;
                    if (control != null)
                    {
                        content = control.Content;
                    }
                }
                if (content != obj2)
                {
                    return content;
                }
            }
            else if (value is uint)
            {
                if (this.type == typeof(bool))
                {
                    return (((uint)value) != 0);
                }
                if (this.type.IsEnum)
                {
                    return Enum.Parse(this.type, Enum.GetName(this.type, value), false);
                }
            }
            return base.ConvertFrom(context, culture, value);
        }

        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            IConvertible convertible = value as IConvertible;
            if ((convertible != null) && typeof(IConvertible).IsAssignableFrom(destinationType))
            {
                return convertible.ToType(destinationType, CultureInfo.InvariantCulture);
            }
            return base.ConvertTo(context, culture, value, destinationType);
        }
        
    }
}

#endif